{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.callbacks import ModelCheckpoint,EarlyStopping,ReduceLROnPlateau,TensorBoard\n",
    "from keras.models import Model\n",
    "from keras import backend as K\n",
    "from keras.optimizers import Adam\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import os\n",
    "from losses import bce_dice_loss\n",
    "from rssegnet import RSSegVGGNet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 从训练集取样本\n",
    "# samples_data_root = 'D:/Data/mc_data/train/images/0/'\n",
    "\n",
    "# filenames = np.random.choice(os.listdir(samples_data_root), 1000)\n",
    "# samples = []\n",
    "# for fn in filenames:\n",
    "#     fullname = samples_data_root + fn\n",
    "#     image = Image.open(fullname)\n",
    "#     image_arr = np.array(image)\n",
    "#     samples.append(image_arr)\n",
    "\n",
    "# sample_images = np.array(samples)\n",
    "# print(sample_images.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def adjust_data(img,mask):\n",
    "    mean_ = np.array([77.79408427,  89.68194542, 101.41694189])\n",
    "    img = (img - mean_) / 255\n",
    "    mask = mask /255\n",
    "    mask[mask > 0.5] = 1\n",
    "    mask[mask <= 0.5] = 0\n",
    "    return (img,mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_train_generator():\n",
    "    train_data_root = 'D:/Data/mc_data/train'  # 训练集存放路径\n",
    "\n",
    "    # data augmentation\n",
    "    # data_gen_args = dict(rotation_range=0.2,\n",
    "    #                     width_shift_range=0.05,\n",
    "    #                     height_shift_range=0.05,\n",
    "    #                     shear_range=0.05,\n",
    "    #                     zoom_range=0.05,\n",
    "    #                     horizontal_flip=True,\n",
    "    #                     fill_mode='nearest')\n",
    "    data_gen_args = dict()\n",
    "\n",
    "    train_image_datagen = ImageDataGenerator(**data_gen_args)\n",
    "    train_mask_datagen = ImageDataGenerator(**data_gen_args)\n",
    "\n",
    "    seed=1\n",
    "\n",
    "    train_image_generator = train_image_datagen.flow_from_directory(\n",
    "        train_data_root + '/images',\n",
    "        target_size=(288,288),\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='rgb')\n",
    "\n",
    "    train_mask_generator = train_mask_datagen.flow_from_directory(\n",
    "        train_data_root + '/masks',\n",
    "        target_size=(288,288),\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='grayscale')\n",
    "\n",
    "    # combine generators into one which yields image and masks\n",
    "    train_generator = zip(train_image_generator, train_mask_generator)\n",
    "    \n",
    "    for (image, mask) in train_generator:\n",
    "#         print(image.shape)\n",
    "#         print(mask.shape)\n",
    "        yield adjust_data(image, mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_val_generator():\n",
    "    val_data_root = 'D:/Data/mc_data/val'  # 验证集存放路径\n",
    "    \n",
    "    # data augmentation\n",
    "    # data_gen_args = dict(rotation_range=0.2,\n",
    "    #                     width_shift_range=0.05,\n",
    "    #                     height_shift_range=0.05,\n",
    "    #                     shear_range=0.05,\n",
    "    #                     zoom_range=0.05,\n",
    "    #                     horizontal_flip=True,\n",
    "    #                     fill_mode='nearest')\n",
    "    data_gen_args = dict()\n",
    "\n",
    "    val_image_datagen = ImageDataGenerator(**data_gen_args)\n",
    "    val_mask_datagen = ImageDataGenerator(**data_gen_args)\n",
    "\n",
    "    seed = 1\n",
    "\n",
    "    val_image_generator = val_image_datagen.flow_from_directory(\n",
    "        val_data_root + '/images',\n",
    "        target_size=(288,288),\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='rgb')\n",
    "\n",
    "    val_mask_generator = val_mask_datagen.flow_from_directory(\n",
    "        val_data_root + '/masks',\n",
    "        target_size=(288,288),\n",
    "        class_mode=None,\n",
    "        batch_size=16,\n",
    "        seed=seed,\n",
    "        color_mode='grayscale')\n",
    "\n",
    "    val_generator = zip(val_image_generator, val_mask_generator)\n",
    "    \n",
    "    for (image, mask) in val_generator:\n",
    "#         print(image.shape)\n",
    "#         print(mask.shape)\n",
    "        yield adjust_data(image, mask)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "image_input (InputLayer)        (None, 288, 288, 3)  0                                            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_20 (Conv2D)              (None, 288, 288, 64) 1792        image_input[0][0]                \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_21 (Conv2D)              (None, 288, 288, 64) 36928       conv2d_20[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_6 (MaxPooling2D)  (None, 144, 144, 64) 0           conv2d_21[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_22 (Conv2D)              (None, 144, 144, 128 73856       max_pooling2d_6[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_23 (Conv2D)              (None, 144, 144, 128 147584      conv2d_22[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_7 (MaxPooling2D)  (None, 72, 72, 128)  0           conv2d_23[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_24 (Conv2D)              (None, 72, 72, 256)  295168      max_pooling2d_7[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_25 (Conv2D)              (None, 72, 72, 256)  590080      conv2d_24[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_26 (Conv2D)              (None, 72, 72, 256)  590080      conv2d_25[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_8 (MaxPooling2D)  (None, 36, 36, 256)  0           conv2d_26[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_27 (Conv2D)              (None, 36, 36, 512)  1180160     max_pooling2d_8[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_28 (Conv2D)              (None, 36, 36, 512)  2359808     conv2d_27[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_29 (Conv2D)              (None, 36, 36, 512)  2359808     conv2d_28[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_9 (MaxPooling2D)  (None, 18, 18, 512)  0           conv2d_29[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_30 (Conv2D)              (None, 18, 18, 512)  2359808     max_pooling2d_9[0][0]            \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_31 (Conv2D)              (None, 18, 18, 512)  2359808     conv2d_30[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_32 (Conv2D)              (None, 18, 18, 512)  2359808     conv2d_31[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "max_pooling2d_10 (MaxPooling2D) (None, 9, 9, 512)    0           conv2d_32[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_33 (Conv2D)              (None, 9, 9, 512)    2359808     max_pooling2d_10[0][0]           \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_6 (Conv2DTrans (None, 18, 18, 256)  1179904     conv2d_33[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_6 (Concatenate)     (None, 18, 18, 768)  0           conv2d_transpose_6[0][0]         \n",
      "                                                                 conv2d_32[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_34 (Conv2D)              (None, 18, 18, 512)  3539456     concatenate_6[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_7 (Conv2DTrans (None, 36, 36, 256)  1179904     conv2d_34[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_7 (Concatenate)     (None, 36, 36, 768)  0           conv2d_transpose_7[0][0]         \n",
      "                                                                 conv2d_29[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_35 (Conv2D)              (None, 36, 36, 512)  3539456     concatenate_7[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_8 (Conv2DTrans (None, 72, 72, 128)  589952      conv2d_35[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_8 (Concatenate)     (None, 72, 72, 384)  0           conv2d_transpose_8[0][0]         \n",
      "                                                                 conv2d_26[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_36 (Conv2D)              (None, 72, 72, 256)  884992      concatenate_8[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_9 (Conv2DTrans (None, 144, 144, 64) 147520      conv2d_36[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_9 (Concatenate)     (None, 144, 144, 192 0           conv2d_transpose_9[0][0]         \n",
      "                                                                 conv2d_23[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_37 (Conv2D)              (None, 144, 144, 128 221312      concatenate_9[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_transpose_10 (Conv2DTran (None, 288, 288, 32) 36896       conv2d_37[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_10 (Concatenate)    (None, 288, 288, 96) 0           conv2d_transpose_10[0][0]        \n",
      "                                                                 conv2d_21[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "conv2d_38 (Conv2D)              (None, 288, 288, 1)  865         concatenate_10[0][0]             \n",
      "==================================================================================================\n",
      "Total params: 28,394,753\n",
      "Trainable params: 28,394,753\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model = RSSegVGGNet.build()\n",
    "model.compile(loss=bce_dice_loss, optimizer=Adam(), metrics=['accuracy'])\n",
    "model.summary()\n",
    "model.load_weights(\"building_seg_vgg16_bcedice_0829.h5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'EarlyStopping' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-13-1ab4459998c8>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m callback_list = [\n\u001b[1;32m----> 2\u001b[1;33m     EarlyStopping(\n\u001b[0m\u001b[0;32m      3\u001b[0m         \u001b[0mmonitor\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'acc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m         \u001b[0mpatience\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m     ),\n",
      "\u001b[1;31mNameError\u001b[0m: name 'EarlyStopping' is not defined"
     ]
    }
   ],
   "source": [
    "callback_list = [\n",
    "    EarlyStopping(\n",
    "        monitor='acc',\n",
    "        patience=5,\n",
    "    ),\n",
    "    ModelCheckpoint(\n",
    "        filepath='building_seg_vgg16_bcedice_0829.h5',\n",
    "        monitor='val_loss',\n",
    "        save_best_only=True,\n",
    "    ),\n",
    "    ReduceLROnPlateau(\n",
    "        monitor='val_loss',\n",
    "        factor=0.1,\n",
    "        patience=3,\n",
    "    ),\n",
    "    TensorBoard(\n",
    "        log_dir = 'logs'\n",
    "    ),\n",
    "]\n",
    "\n",
    "history = model.fit_generator(make_train_generator(),\n",
    "                              epochs=300,\n",
    "                              steps_per_epoch=12000,\n",
    "                              validation_data=make_val_generator(),\n",
    "                              validation_steps=50,\n",
    "                              callbacks=callback_list,\n",
    "                              verbose=1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
